import requests
import hmac
import hashlib
import time
import json
from decimal import Decimal


def check_account_balance(api_key, api_secret, testnet=True):
    """检查账户余额"""
    base_url = "https://testnet.binance.vision" if testnet else "https://api.binance.com"

    print("=== 账户余额检查 ===")

    # 获取账户信息
    endpoint = "/api/v3/account"
    timestamp = int(time.time() * 1000)

    # 获取准确的服务器时间
    try:
        time_response = requests.get(f"{base_url}/api/v3/time")
        timestamp = time_response.json()['serverTime']
    except:
        pass

    params = f"timestamp={timestamp}&recvWindow=5000"
    signature = hmac.new(
        api_secret.encode('utf-8'),
        params.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()

    url = f"{base_url}{endpoint}?{params}&signature={signature}"
    headers = {"X-MBX-APIKEY": api_key}

    try:
        response = requests.get(url, headers=headers, timeout=10)
        if response.status_code == 200:
            account_info = response.json()

            print("账户余额概览:")
            print("-" * 50)

            # 显示所有有余额的资产
            has_balance = False
            for asset in account_info['balances']:
                free = Decimal(asset['free'])
                locked = Decimal(asset['locked'])
                total = free + locked

                if total > 0:
                    has_balance = True
                    print(f"{asset['asset']}:")
                    print(f"  可用: {free}")
                    print(f"  锁定: {locked}")
                    print(f"  总计: {total}")
                    print()

            if not has_balance:
                print("❌ 账户中没有检测到任何余额")
                return False

            return account_info
        else:
            error_data = response.json()
            print(f"❌ 获取账户信息失败: {error_data}")
            return None
    except Exception as e:
        print(f"❌ 检查余额时发生错误: {e}")
        return None


def calculate_order_cost(symbol, quantity, price=None, testnet=True):
    """计算订单所需资金"""
    base_url = "https://testnet.binance.vision" if testnet else "https://api.binance.com"

    # 如果未提供价格，获取当前市场价格
    if price is None:
        try:
            ticker_response = requests.get(f"{base_url}/api/v3/ticker/price?symbol={symbol}")
            price = Decimal(ticker_response.json()['price'])
            print(f"当前 {symbol} 价格: {price}")
        except Exception as e:
            print(f"❌ 无法获取市场价格: {e}")
            return None

    # 获取交易对信息
    try:
        exchange_info = requests.get(f"{base_url}/api/v3/exchangeInfo?symbol={symbol}")
        symbol_info = exchange_info.json()

        for s in symbol_info['symbols']:
            if s['symbol'] == symbol:
                # 计算订单总成本
                base_asset = s['baseAsset']  # 如 BNB
                quote_asset = s['quoteAsset']  # 如 USDT

                quantity_decimal = Decimal(str(quantity))
                price_decimal = Decimal(str(price))
                total_cost = quantity_decimal * price_decimal

                print(f"\n订单成本计算:")
                print(f"交易对: {symbol}")
                print(f"数量: {quantity} {base_asset}")
                print(f"价格: {price} {quote_asset}")
                print(f"总成本: {total_cost} {quote_asset}")

                # 检查最小交易金额
                for filter_item in s['filters']:
                    if filter_item['filterType'] == 'MIN_NOTIONAL':
                        min_notional = Decimal(filter_item['minNotional'])
                        print(f"最小交易金额: {min_notional} {quote_asset}")

                        if total_cost < min_notional:
                            print(f"❌ 交易金额 {total_cost} 小于最小要求 {min_notional}")
                            required_quantity = min_notional / price_decimal
                            print(f"建议最小数量: {required_quantity:.6f} {base_asset}")

                return {
                    'base_asset': base_asset,
                    'quote_asset': quote_asset,
                    'quantity': quantity_decimal,
                    'price': price_decimal,
                    'total_cost': total_cost
                }
    except Exception as e:
        print(f"❌ 计算订单成本时发生错误: {e}")
        return None


# 使用示例

API_KEY = "oMlYVBgANplqH7XilK0rzJ47r7p1R3MWoywVNBYOGvj5UHYXebQnxZjX9kLpdd5V"
API_SECRET = "8587vRjV45QsPPXhlrn3vcBdUwQJFA6HIBqfaVbJO7UqhhqTcVrQCR4GEO6w4OtN"
# 1. 检查账户余额
account_info = check_account_balance(API_KEY, API_SECRET, testnet=False)

# 2. 计算订单成本（以购买0.01 BNB为例）
if account_info:
    order_cost = calculate_order_cost("BNBUSDT", 0.01, 969.38, testnet=False)